package com.ppch.zerocodegenerator.ai.tools;

import com.ppch.zerocodegenerator.model.constant.AppConstant;
import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;
import dev.langchain4j.agent.tool.ToolMemoryId;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

/**
 * 文件写入工具类
 */
@Slf4j
public class FileWriteTool {

    /**
     * 写入文件到指定路径
     * @param relativeFilePath 文件保存的相对路径
     * @param content 内容
     * @param appId 应用ID（支持模型上下文传参：可以将提供给AI Service方法的值将自动传递给@Tool方法。
     *                      注意在写AI Service接口时需要这样传入这个参数：@MemoryId Long appId）
     * @return 文件相对路径
     */
    @Tool("写入文件到指定路径")
    public String writeFile(@P("文件的相对路径") String relativeFilePath,
                            @P("要写入文件的内容") String content,
                            @ToolMemoryId Long appId) {
        try {
            log.warn("WriteFile工具被调用，开始写入文件......");
            Path path = Paths.get(relativeFilePath);  // 将字符串路径转换为Path对象

            if (!path.isAbsolute()) {  // 检查是否为绝对路径
                // 如果不是绝对路径，基于appId创建项目目录
                String projectDirName = "vue_project_" + appId;
                // 构建完整的项目根路径：CODE_OUTPUT_ROOT_DIR + vue_project_appId
                Path projectRoot = Paths.get(AppConstant.CODE_OUTPUT_ROOT_DIR, projectDirName);
                path = projectRoot.resolve(relativeFilePath);  // 将相对路径解析为绝对路径
            }

            // 创建父目录（如果不存在）
            Path parentDir = path.getParent();
            if (parentDir != null) {
                Files.createDirectories(parentDir);  // 递归创建所有不存在的父目录
            }

            // 写入文件内容
            Files.write(path, content.getBytes(),  // 将内容转换为字节数组并写入文件
                    StandardOpenOption.CREATE,  // 如果文件不存在则创建
                    StandardOpenOption.TRUNCATE_EXISTING);  // 如果文件存在则清空内容

            log.info("成功写入文件: {}", path.toAbsolutePath());  // 记录成功日志
            return "文件写入成功: " + relativeFilePath;  // 返回相对路径给调用者

        } catch (IOException e) {
            String errorMessage = "文件写入失败: " + relativeFilePath + ", 错误: " + e.getMessage();
            log.error(errorMessage, e);  // 记录错误日志
            return errorMessage;  // 返回错误信息
        }
    }
}

